//    Copyright (C) Kherty.  All rights reserved.

using System;
using System.Diagnostics.Contracts;
using System.Windows.Media;
using OpenLS.Core.Serialization;
using OpenLS.Drawing;

namespace OpenLS.Spreadsheet
{
    /// <summary>
    /// Contains information about the border of a cell
    /// </summary>
    public class Border : IOfficeXmlSerializableAs
    {
        private BorderStyle _style = BorderStyle.Thin;
        private SpreadsheetColor _color;

        public Border()
        {
        }

        internal double GetThickness()
        {
            switch (Style)
            {
                case BorderStyle.None:
                    return 0;
                case BorderStyle.Double:
                    return 1;
                case BorderStyle.Thick:
                    return 3;
                case BorderStyle.DashDot:
                case BorderStyle.DashDotDot:
                case BorderStyle.Dashed:
                case BorderStyle.Thin:
                    return 1;
                case BorderStyle.MediumDashDot:
                case BorderStyle.MediumDashDotDot:
                case BorderStyle.MediumDashed:
                case BorderStyle.Medium:
                    return 2;
                case BorderStyle.Dotted:
                    return 1;
                case BorderStyle.Hair:
                    return 1;
                case BorderStyle.SlantDashDot:
                    return 2;

                default:
                    throw new NotSupportedException();
            }
        }


        public Border(BorderStyle style, SpreadsheetColor color)
        {
            Contract.Requires(!(style != BorderStyle.None && color == null));
            _style = style;
            Color = color;
        }

        public Border(BorderStyle style)
        {
            _style = style;
        }

        public Border(SpreadsheetColor color)
        {
            Color = color;
        }

        public BorderStyle Style
        {
            get { return _style; }
            internal set { _style = value; }
        }

        public SpreadsheetColor Color
        {
            get { return _color; }
            set { _color = value; }
        }

        #region IOfficeXmlSerializableAs Members

        void IOfficeXmlSerializableAs.ReadXmlAs(string name, ReadContext context)
        {
            using (ReadContext c = context.Read(name))
            {
                Style = c.GetOptionalEnum("style", BorderStyle.None);
                if (c.ReaderLocalName == "color")
                    Color = SpreadsheetColor.ReadColor("color", c); //\\null?
            }
        }

        void IOfficeXmlSerializableAs.WriteXmlAs(string name, WriteContext context)
        {
            using (WriteContext c = context.Write(name))
            {
                c.SetOptionalEnum("style", Style, BorderStyle.None);
                if (Color != null)
                    Color.WriteXmlAs("color", c);
            }
        }

        #endregion

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj)) return false;
            if (ReferenceEquals(this, obj)) return true;
            if (obj.GetType() != typeof (Border)) return false;
            return Equals((Border) obj);
        }

        private bool Equals(Border other)
        {
            if (ReferenceEquals(null, other)) return false;
            if (ReferenceEquals(this, other)) return true;
            return Equals(other._style, _style) && Equals(other._color, _color);
        }

        public override int GetHashCode()
        {
            unchecked
            {
                return (_style.GetHashCode()*397) ^ (_color != null ? _color.GetHashCode() : 0);
            }
        }

        public override string ToString()
        {
            return "Style = " + Style + " Color = " + Color;
        }

        internal Color GetWPFColor(ColorScheme colorScheme)
        {
            if (Color != null)
                return Color.GetColor(colorScheme);
            return Colors.Black;
        }


        internal static Border Create(BorderStyle style)
        {
            var result = new Border {Style = style};
            return result;
        }
    }
}